use crate::math::{Value, Polynomial, Monomial, Signed, Sign, Equation, PolyChild};
use egui_dy::eframe::egui::{vec2, Label, Ui, WidgetText};
use crate::char_utils::char_to_italic_str;
fn no_select_label(ui: &mut Ui, text: impl Into<WidgetText>) {
    let label = Label::new(text).selectable(false);
    ui.add(label);
}
impl Value {
    pub fn render(&self, ui: &mut Ui, size: f32) {
        match self {
            Value::Mono(monomial) => monomial.render(ui, size),
            Value::Poly(polynomial) => polynomial.render(ui, size),
            Value::Signed(signed) => signed.render(ui, size),
            Value::Var(variable) => no_select_label(ui, char_to_italic_str(variable.main)),
            Value::Num(number) => no_select_label(ui, number.to_string())
        }
    }
    fn bracket_render(&self, ui: &mut Ui, size: f32) {
        no_select_label(ui, "(");
        self.render(ui, size);
        no_select_label(ui, ")");
    }
}
impl Monomial {
    fn render(&self, ui: &mut Ui, size: f32) {
        for child in &self.children {
            match child {
                Value::Mono(_) | Value::Poly(_) | Value::Signed(_) => child.bracket_render(ui, size),
                _ => child.render(ui, size),
            }
        }
    }
}
impl Sign {
    pub fn render(&self, ui: &mut Ui, size: f32) {
        ui.allocate_space(vec2(size * 0.2, size));
        match self {
            Self::Pos => no_select_label(ui, "+"),
            Self::Neg => no_select_label(ui, "-")
        }
        ui.allocate_space(vec2(size * 0.2, size));
    }
}
impl Polynomial {
    fn render(&self, ui: &mut Ui, size: f32) {
        if self[0].sign == Sign::Neg {
            self[0].sign.render(ui, size);
        }
        match self[0].inner {
            Value::Poly(_) => self[0].inner.bracket_render(ui, size),
            _ => self[0].inner.render(ui, size)
        }
        for i in 1..self.len() {
            self[i].render(ui, size);
        }
    }
}
impl PolyChild {
    pub fn render(&self, ui: &mut Ui, size: f32) {
        self.sign.render(ui, size);
        if let Value::Poly(_) | Value::Signed(_) = self.inner {
            self.inner.bracket_render(ui, size);
        } else {
            self.inner.render(ui, size);
        }
    }
}
impl Signed {
    fn render(&self, ui: &mut Ui, size: f32) {
        self.sign.render(ui, size);
        match &*self.inner {
            Value::Signed(_) | Value::Poly(_) => self.inner.bracket_render(ui, size),
            _ => self.inner.render(ui, size)
        }
    }
}
impl Equation {
    pub fn render(&self, ui: &mut Ui, size: f32) {
        self.left.render(ui, size);
        ui.allocate_space(vec2(size * 0.2, size));
        no_select_label(ui, "=");
        ui.allocate_space(vec2(size * 0.2, size));
        self.right.render(ui, size);
    }
}